/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.to.aboomy.bannersample.indicator;

import com.to.aboomy.banner.Indicator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.util.ArrayList;
import java.util.List;

/**
 * SWAPIndicatorView指示器
 *
 * @since 2021-08-09
 */
public class SwapIndicatorView extends DirectionalLayout implements Indicator {
    private static final int NUM_10 = 10;
    private static final int NUM_30 = 30;
    private static final int NUM_90 = 90;
    private static final int NUM_300 = 300;
    private static final int NUM_5 = 5;
    private static final int NUM_15 = 15;
    private static final int NUM_2 = 2;
    private int pagerCount = 0;
    /**
     * 控制在banner中的位置
     */
    private DependentLayout.LayoutConfig params;
    private int pointRadius = NUM_10;
    private int pointSelectColor = Color.RED.getValue();

    private int pointColor = Color.GRAY.getValue();
    private int pointWidth = pointRadius * NUM_5;
    private int spacing = NUM_15;
    private float indicatorSelectedRadius;
    private int selectedPage = 0;
    private float indicatorRadius = (float) pointWidth / NUM_2;
    private float indicatorRatio = 1.0f;
    private boolean isSquare;
    private List<Text> linkedList = new ArrayList<>();

    /**
     * 构造
     *
     * @param context
     */
    public SwapIndicatorView(Context context) {
        this(context, null, null);
    }

    /**
     * 构造
     *
     * @param context
     * @param attrSet
     * @param styleName
     */
    public SwapIndicatorView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        setOrientation(DirectionalLayout.HORIZONTAL);
        linkedList.clear();
        indicatorSelectedRadius = (float) pointWidth / NUM_2;
    }

    @Override
    public void initIndicatorCount(int pagerCount1) {
        isSquare = true;
        this.pagerCount = pagerCount1;
        setVisibility(pagerCount1 > 1 ? VISIBLE : HIDE);
        removeAllComponents();
        DirectionalLayout.LayoutConfig lp = new DirectionalLayout.LayoutConfig(LayoutConfig.MATCH_CONTENT,
                DirectionalLayout.LayoutConfig.MATCH_CONTENT);
        lp.setMarginLeft(spacing);
        lp.setMarginRight(spacing);
        for (int i1 = 0; i1 < pagerCount1; i1++) {
            // 翻页指示的点
            Text pointView = new Text(getContext());
            pointView.setLayoutConfig(lp);
            ShapeElement drawable = new ShapeElement();
            drawable.setCornerRadius(NUM_90);
            int temp = 0;
            if (temp == i1) {
                pointView.setWidth(pointWidth);
                drawable.setRgbColor(RgbColor.fromArgbInt(pointSelectColor));
            } else {
                pointView.setWidth(pointWidth);
                drawable.setRgbColor(RgbColor.fromArgbInt(pointColor));
            }
            pointView.setHeight(pointWidth);
            pointView.setBackground(drawable);
            linkedList.add(pointView);
            addComponent(pointView);
        }
    }

    @Override
    public Component getView() {
        return this;
    }

    @Override
    public DependentLayout.LayoutConfig getParams() {
        if (params == null) {
            params = new DependentLayout.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_CONTENT,
                    ComponentContainer.LayoutConfig.MATCH_CONTENT);
            params.addRule(DependentLayout.LayoutConfig.ALIGN_PARENT_BOTTOM);
            params.addRule(DependentLayout.LayoutConfig.CENTER_IN_PARENT);
            params.setMarginBottom(NUM_30);
        }
        return params;
    }

    @Override
    public void setAutoStau(Boolean isAuto) {
    }

    @Override
    public void onPageSliding(int position, float positionOffset, int positionOffsetPixels) {
        if (positionOffsetPixels > 0) {
            isSquare = true;
        } else {
            isSquare = false;
        }
    }

    @Override
    public void onPageSlideStateChanged(int i) {
    }

    @Override
    public void onPageChosen(int position) {
        selectedPage = position;
        selectPoint(position);
    }

    /**
     * 选中点
     *
     * @param position
     */
    public void selectPoint(int position) {
        final int count = getChildCount();
        if (position >= 0 && position < count) {
            int lastIndex = getLastPageIndex(position);
            Text lastPointView = linkedList.get(lastIndex);
            float nowx = indicatorStartX(selectedPage);
            float lastx = indicatorStartX(getLastPageIndex(selectedPage));

            AnimatorProperty animatorProperty = new AnimatorProperty();
            animatorProperty.setDuration(NUM_300);
            animatorProperty.moveFromX(lastx);
            animatorProperty.moveToX(nowx);
            animatorProperty.setTarget(lastPointView);
            animatorProperty.start();
            Text pointView = linkedList.get(position);
            AnimatorProperty animatorProperty2 = new AnimatorProperty();
            animatorProperty2.setDuration(NUM_300);
            animatorProperty2.moveFromX(nowx);
            animatorProperty2.moveToX(lastx);
            animatorProperty2.setTarget(pointView);
            animatorProperty2.start();
            swap(linkedList, position, lastIndex);
        }
    }

    /**
     * 交换位置
     *
     * @param list
     * @param index
     * @param index2
     */
    public void swap(List<Text> list, int index, int index2) {
        Text text = list.get(index);
        list.set(index, list.get(index2));
        list.set(index2, text);
    }

    /**
     * 通过索引值获取x位置
     *
     * @param index index
     * @return x
     */
    private float indicatorStartX(int index) {
        int pointSpacing = spacing * NUM_2;
        float centerX = spacing + (pointWidth + pointSpacing) * index;
        return centerX;
    }

    /**
     * 计算上一个索引值
     *
     * @param selectedPage1
     * @return 索引值
     */
    private int getLastPageIndex(int selectedPage1) {
        int lastPageIndex = 0;
        if (isSquare) {
            int temp = 0;
            if (temp == selectedPage1) {
                lastPageIndex = pagerCount - 1;
            } else {
                lastPageIndex = selectedPage1 - 1;
            }
        } else {
            int temp2 = pagerCount - 1;
            if (temp2 == selectedPage1) {
                lastPageIndex = 0;
            } else {
                lastPageIndex = selectedPage1 + 1;
            }
        }

        return lastPageIndex;
    }

    /**
     * getRatioRadius
     *
     * @return float
     */
    private float getRatioRadius() {
        return indicatorRadius * indicatorRatio;
    }

    /**
     * getRatioSelectedRadius
     *
     * @return float
     */
    private float getRatioSelectedRadius() {
        return indicatorSelectedRadius * 1.0F;
    }
}
